<?php

namespace app\model\oa;

use app\model\BaseModel;

/**
 * 工作通知模型
 * 对应数据表：oa_work_notice
 */
class WorkNotice extends BaseModel
{
    /**
     * 数据表名
     * @var string
     */
    protected $name = 'work_notice';

    /**
     * 主键名
     * @var string
     */
    protected $pk = 'id';

    /**
     * 字段类型转换
     * @var array
     */
    protected $type = [
        'id' => 'integer',
        'title' => 'string',
        'content' => 'string',
        'type' => 'integer',
        'receiver_type' => 'integer',
        'receiver_ids' => 'string',
        'sender_id' => 'integer',
        'is_read' => 'integer',
        'create_time' => 'integer',
        'update_time' => 'integer',
    ];

    /**
     * 可搜索字段
     * @var array
     */
    protected $searchField = ['title', 'content'];

    /**
     * 通知类型
     * @var array
     */
    public const TYPE = [
        1 => '系统通知',
        2 => '工作提醒',
        3 => '任务分配',
        4 => '审批提醒',
        5 => '消息通知',
    ];

    /**
     * 接收者类型
     * @var array
     */
    public const RECEIVER_TYPE = [
        1 => '指定用户',
        2 => '部门用户',
        3 => '全部用户',
    ];

    /**
     * 关联发送者
     * @return \think\model\relation\BelongsTo
     */
    public function sender()
    {
        return $this->belongsTo('app\model\admin\User', 'sender_id', 'id');
    }

    /**
     * 获取通知列表
     * @param array $params 查询参数
     * @return \think\Paginator
     */
    public function getNoticeList($params = [])
    {
        $where = [];
        
        if (!empty($params['type'])) {
            $where[] = ['type', '=', $params['type']];
        }
        
        if (!empty($params['sender_id'])) {
            $where[] = ['sender_id', '=', $params['sender_id']];
        }
        
        if (isset($params['is_read']) && $params['is_read'] !== '') {
            $where[] = ['is_read', '=', $params['is_read']];
        }

        return $this->where($where)
            ->with(['sender'])
            ->order('id', 'desc')
            ->paginate([
                'list_rows' => $params['limit'] ?? 15,
                'page' => $params['page'] ?? 1,
            ]);
    }

    /**
     * 标记通知为已读
     * @param int|array $ids 通知ID
     * @return bool
     */
    public function markAsRead($ids)
    {
        try {
            $result = 0;
            if (is_array($ids)) {
                $result = $this->where('id', 'in', $ids)->update(['is_read' => 1, 'update_time' => time()]);
            } else {
                $result = $this->where('id', $ids)->update(['is_read' => 1, 'update_time' => time()]);
            }
            // 返回布尔值：受影响行数大于0表示成功
            return $result > 0;
        } catch (\Exception $e) {
            // 发生异常时返回false
            return false;
        }
    }

    /**
     * 获取未读通知数量
     * @param int|null $userId 用户ID
     * @return int
     */
    public function getUnreadCount($userId = null)
    {
        $where = [['is_read', '=', 0]];
        
        if ($userId) {
            $where[] = ['receiver_ids', 'like', '%"' . $userId . '"%'];
        }

        return $this->where($where)->count();
    }

    /**
     * 发送通知
     * @param string $title 通知标题
     * @param string $content 通知内容
     * @param int $type 通知类型
     * @param int $receiverType 接收者类型
     * @param array $receiverIds 接收者ID数组
     * @param int $senderId 发送者ID
     * @return bool
     */
    public function sendNotice($title, $content, $type, $receiverType, $receiverIds = [], $senderId = 0)
    {
        try {
            $result = $this->save([
                'title' => $title,
                'content' => $content,
                'type' => $type,
                'receiver_type' => $receiverType,
                'receiver_ids' => json_encode($receiverIds),
                'sender_id' => $senderId,
                'is_read' => 0,
                'create_time' => time(),
                'update_time' => time(),
            ]);
            // save()方法成功时返回数据或true，失败时返回false
            return $result !== false;
        } catch (\Exception $e) {
            // 发生异常时返回false
            return false;
        }
    }

    /**
     * 搜索器：按类型搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchTypeAttr($query, $value)
    {
        $query->where('type', $value);
    }

    /**
     * 搜索器：按阅读状态搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchIsReadAttr($query, $value)
    {
        $query->where('is_read', $value);
    }

    /**
     * 搜索器：按标题搜索
     * @param \think\db\Query $query
     * @param string $value
     */
    public function searchTitleAttr($query, $value)
    {
        $query->where('title', 'like', '%' . $value . '%');
    }
}